//The MIT License
//
//Copyright (c) 2009 nodchip
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package tv.dyndns.kishibe.client;

import tv.dyndns.kishibe.client.game.GameMode;
import tv.dyndns.kishibe.client.packet.PacketRegistrationData;
import tv.dyndns.kishibe.client.packet.PacketServerStatus;
import tv.dyndns.kishibe.client.util.SerialTimer;

import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class SceneLobby implements SceneBase {
	public static final int SESSION_TYPE_VS_COM = 0;
	public static final int SESSION_TYPE_WHOLE = 1;
	public static final int SESSION_TYPE_EVENT = 2;
	public static final int SESSION_TYPE_THEME = 3;
	private PanelLobby panel = new PanelLobby(this);
	private boolean isFirst = true;
	private final Timer timerUpdateServerStatus = new SerialTimer() {
		public void run() {
			updateServerData();
		}
	};
	private boolean addPenalty = false;

	public SceneLobby() {
		Controller.getInstance().setGamePanel(panel);

		updateServerData();
	}

	private void updateServerData() {
		int userCode = UserData.getInstance().getUserCode();

		Service.Util.getInstance().getServerStatus(isFirst, userCode, callbackGetServerStatus);
		isFirst = false;
	}

	private final AsyncCallback<PacketServerStatus> callbackGetServerStatus = new AsyncCallback<PacketServerStatus>() {
		public void onSuccess(PacketServerStatus result) {
			if (panel != null) {
				panel.setServerStatus(result);
				panel.setLastestPlayers(result.lastestPlayers);
			}
		}

		public void onFailure(Throwable caught) {
			Controller.getInstance().showErrorMessage("SceneRegistration.SceneRegistration() - サーバー状態の取得に失敗しました。パケットを再送します。");
		}
	};

	public void register(int sessionType) {
		final String playlerName = panel.getPlayerName();
		final int genre = panel.getGenre();
		final int type = panel.getType();
		final String greeting = panel.getGreeting();
		final boolean newProblem = panel.getNewProblem();
		final boolean publicEvent = panel.getPublicEvent();

		final UserData record = UserData.getInstance();
		final int classNumber = record.getClassLevel();
		int classLevel = classNumber / Constant.STEP_PER_CLASS_LEVEL;
		if (classLevel >= Constant.MAX_CLASS_LEVEL) {
			classLevel = Constant.MAX_CLASS_LEVEL;
		}
		final String imageFileName = record.getImageFileName();

		final GameMode gameMode;
		final String roomName;
		final String theme;
		switch (sessionType) {
		case SESSION_TYPE_VS_COM: {
			gameMode = GameMode.vsCom;
			roomName = null;
			theme = null;
			SharedData.getInstance().setEvent(false);
			SharedData.getInstance().setThemeMode(false);
			addPenalty = false;
			break;
		}
		case SESSION_TYPE_WHOLE: {
			gameMode = GameMode.whole;
			roomName = null;
			theme = null;
			SharedData.getInstance().setEvent(true);
			SharedData.getInstance().setThemeMode(false);
			addPenalty = true;
			break;
		}
		case SESSION_TYPE_EVENT: {
			gameMode = GameMode.event;
			roomName = panel.getEventName();
			theme = null;
			SharedData.getInstance().setEvent(true);
			SharedData.getInstance().setThemeMode(false);
			addPenalty = true;
			break;
		}
		case SESSION_TYPE_THEME: {
			gameMode = GameMode.theme;
			roomName = null;
			theme = panel.getThemeModeTheme();
			SharedData.getInstance().setEvent(true);
			SharedData.getInstance().setThemeMode(true);
			addPenalty = false;
			break;
		}
		default: {
			gameMode = null;
			roomName = null;
			theme = null;
			SharedData.getInstance().setEvent(false);
			addPenalty = true;
			break;
		}
		}

		final int difficultSelect = panel.getDifficultSelect();
		final int rating = UserData.getInstance().getRating();
		final int userCode = UserData.getInstance().getUserCode();
		Service.Util.getInstance().register(playlerName, genre, type, greeting, gameMode, roomName, theme, imageFileName, classLevel, difficultSelect, rating, userCode, newProblem, publicEvent, callbackRegister);
	}

	private final AsyncCallback<PacketRegistrationData> callbackRegister = new AsyncCallback<PacketRegistrationData>() {
		public void onSuccess(PacketRegistrationData result) {
			SharedData.getInstance().setPlayerId(result.playerId);
			SharedData.getInstance().setPlayerListIndex(result.playerListIndex);
			SharedData.getInstance().setSessionId(result.sessionId);

			// シーン切り替え
			Controller.getInstance().setScene(new SceneMatching(addPenalty));
			panel = null;
		}

		public void onFailure(Throwable caught) {
			Controller.getInstance().showErrorMessage("PanelRegistration.PanelRegistration() - 登録処理に失敗しました。頻繁に発生する場合は管理者に御連絡ください。");
			Controller.getInstance().showErrorMessage(caught.getLocalizedMessage());
		}
	};

	public void onLoad() {
		timerUpdateServerStatus.scheduleRepeating(10000);
	}

	public void onUnload() {
		timerUpdateServerStatus.cancel();
	}
}
